﻿using System;
using System.Linq;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using WxOpenPLatCore.DBContext;
using WxOpenPLatCore.Models;
using WxOpenPLatCore.Services;
using WxOpenPlatLibCore;
using WxOpenPlatLibCore.Utils;

namespace dotnetcore_Demo.Controllers
{
    public class weixinController : Controller
    {
        private string token = "jmsoeasy";
        private WXApiFunction wx = new WXApiFunction();

        private readonly Microsoft.AspNetCore.Hosting.IWebHostEnvironment _webHostEnvironment;
        private readonly DomainsService _service;
        private readonly WeixinMpsService _mpsservice;
        public weixinController(Microsoft.AspNetCore.Hosting.IWebHostEnvironment webHostEnvironment, DomainsService service, WeixinMpsService mpservice)
        {
            _webHostEnvironment = webHostEnvironment;
            _service = service;
            _mpsservice = mpservice;
        }

        [Route("component_verify_ticket.aspx")]
        public void component_verify_ticket()
        {
            if (!System.IO.Directory.Exists(_webHostEnvironment.ContentRootPath + "/Cache/"))
            {
                System.IO.Directory.CreateDirectory(_webHostEnvironment.ContentRootPath + "/Cache/");
            }

            //公众平台上开发者设置的token, appID, EncodingAESKey
            string sToken = WXConfig.sToken;
            string sAppID = WXConfig.sAppID;
            string sEncodingAESKey = WXConfig.sEncodingAESKey;

            System.IO.StreamReader requestReader = new System.IO.StreamReader(Request.Body);
            WXBizMsgCrypt wxcpt = new WXBizMsgCrypt(sToken, sEncodingAESKey, sAppID);

            string sReqTimeStamp = Request.Query["timestamp"];
            string sReqNonce = Request.Query["nonce"];
            string encrypt_type = Request.Query["encrypt_type"];
            string sReqMsgSig = Request.Query["msg_signature"];
            string sReqData = requestReader.ReadToEnd();
            requestReader.Close();

            string sMsg = "";  //解析之后的明文
            int ret = 0;
            ret = wxcpt.DecryptMsg(sReqMsgSig, sReqTimeStamp, sReqNonce, sReqData, ref sMsg);
            if (ret != 0)
            {
                Response.WriteAsync("ERR: Decrypt fail, ret: " + ret);
                return;
            }
            else
            {
                System.Xml.XmlDocument doc = new System.Xml.XmlDocument();
                doc.LoadXml(sMsg);
                System.Xml.XmlNode node = doc.FirstChild;
                if (node != null && node["InfoType"].InnerText == "component_verify_ticket")
                {
                    string ComponentVerifyTicket = node["ComponentVerifyTicket"].InnerText;
                    string filepath = _webHostEnvironment.ContentRootPath + "/Cache/ComponentVerifyTicket";
                    if (System.IO.File.Exists(filepath))
                    {
                        System.IO.File.Delete(filepath);
                    }
                    System.IO.File.AppendAllText(filepath, ComponentVerifyTicket);
                }
            }

            Response.Clear();
            Response.WriteAsync("success");
        }

        [Route("wxvalidate.ashx")]
        public void wxvalidate()
        {
            Response.ContentType = "text/plain";
            if (Request.Method.ToUpper() == "POST")
            {
                try
                {
                    wx.RequestMsg();
                }
                catch (Exception ex)
                {
                    WXComm.WriteLog("报错了---" + ex.Message + "--" + ex.Source + "--" + ex.StackTrace);
                }
            }
            else
            {
                string echoStr = Request.Query["echoStr"];
                if (wx.CheckSignature(token))
                {
                    if (!string.IsNullOrEmpty(echoStr))
                    {
                        Response.WriteAsync(echoStr);
                    }
                }
            }
        }

        [Route("getauthcode")]
        public void get_auth_code()
        {
            if (CacheHelper.Get("pre_auth_code_expires") == null)
            {
                WXComponent.GetPreAuthCode();
            }
            if (string.IsNullOrEmpty(Request.Query["auth_code"]))
            {
                Response.Redirect(string.Format("https://mp.weixin.qq.com/cgi-bin/componentloginpage?component_appid={0}&pre_auth_code={1}&redirect_uri={2}",
                    WXConfig.sAppID,
                    CacheHelper.Get("pre_auth_code"),
                    System.Net.WebUtility.UrlEncode(GetAbsoluteUri())
                ));
            }
            else
            {
                string auth_code = Request.Query["auth_code"];
                Console.WriteLine("auth_code:" + auth_code);
                DeserializeJson dic = WXComponent.GetAuthorizationInfo(auth_code);
                string authorizer_appid = dic.GetString("authorization_info.authorizer_appid");
                Console.WriteLine("authorizer_appid:" + authorizer_appid);
                if (!string.IsNullOrEmpty(authorizer_appid))
                {
                    string authorizer_access_token = dic.GetString("authorization_info.authorizer_access_token");
                    string authorizer_refresh_token = dic.GetString("authorization_info.authorizer_refresh_token");
                    dic = WXComponent.GetAuthorizerAccountInfo(authorizer_appid);

                    Response.WriteAsync(dic.GetString("authorization_info.authorizer_appid"));
                    WeixinMps model = _mpsservice.GetByAppId(authorizer_appid) ?? new WeixinMps() { id = 0, updatetime = DateTime.Now };
                    model.appid = dic.GetString("authorization_info.authorizer_appid");
                    model.access_token = authorizer_access_token;
                    model.refresh_token = authorizer_refresh_token;
                    model.nick_name = dic.GetString("authorizer_info.nick_name");
                    model.head_img = dic.GetString("authorizer_info.head_img");
                    model.user_name = dic.GetString("authorizer_info.user_name");
                    model.alias = dic.GetString("authorizer_info.alias");
                    model.qrcode_url = dic.GetString("authorizer_info.qrcode_url");
                    model.principal_name = dic.GetString("authorizer_info.principal_name");
                    model.signature = dic.GetString("authorizer_info.signature");
                    model.updatetime = DateTime.Now;
                    //model.access_token = dic.GetString("authorizer_info.authorizer_appid");
                    //model.refresh_token = dic.GetString("authorizer_info.refresh_token");
                    _mpsservice.AddOrUpdate(model);
                    CacheHelper.Remove("pre_auth_code_expires");
                    CacheHelper.Remove("pre_auth_code");
                }
            }
        }

        [Route("getcode.aspx")]
        public void getcode()
        {
            if (string.IsNullOrEmpty(Request.Query["code"]))
            {
                var urlReferrer = Request.Headers["Referer"].FirstOrDefault();
                if (string.IsNullOrEmpty(urlReferrer))
                {
                    Response.WriteAsync("无效的来源");
                    return;
                }
                Uri uri = new Uri(urlReferrer);
                Domains model = _service.GetByHost(uri.Host);
                if (model == null)
                {
                    Response.WriteAsync("授权域名不存在");
                    return;
                }
                Response.Redirect(string.Format("https://open.weixin.qq.com/connect/oauth2/authorize?appid={0}&redirect_uri={1}&response_type=code&scope={3}&state={4}&component_appid={2}#wechat_redirect",
                        model.appid,
                        System.Net.WebUtility.UrlEncode(GetAbsoluteUri()),
                        WXConfig.sAppID,
                        (model.scope == 1 ? "snsapi_userinfo" : "snsapi_base"),//"snsapi_base"
                        model.state
                    ));
            }
            else
            {
                string state = Request.Query["state"];
                Domains model = _service.GetByState(state);
                if (model == null)
                {
                    Response.Redirect("/index.html");
                }
                string url = string.Format("https://api.weixin.qq.com/sns/oauth2/component/access_token?appid={0}&code={1}&grant_type=authorization_code&component_appid={2}&component_access_token={3}", model.appid, Request.Query["code"], WXConfig.sAppID, WXComponent.GetComponentAccessToken(WXConfig.sAppID));
                System.Net.WebClient wc = new System.Net.WebClient();
                wc.Encoding = System.Text.Encoding.UTF8;
                string jsonstr = wc.DownloadString(url);
                if (model.scope == 1)
                {
                    Newtonsoft.Json.Linq.JObject json = Newtonsoft.Json.Linq.JObject.Parse(jsonstr);
                    string openid = json.GetValue("openid").ToString();
                    url = string.Format("https://api.weixin.qq.com/sns/userinfo?access_token={0}&openid={1}&lang=zh_CN", json.GetValue("access_token"), openid);
                    jsonstr = wc.DownloadString(url);
                }
                else
                {
                    Newtonsoft.Json.Linq.JObject json = Newtonsoft.Json.Linq.JObject.Parse(jsonstr);
                    jsonstr = "{\"openid\":\"" + json.GetValue("openid") + "\"}";
                }
                Response.Redirect(model.callback + (model.callback.Contains("?") ? "&" : "?") + model.jkey + "=" + System.Net.WebUtility.UrlEncode(jsonstr));
            }
        }

        public string GetAbsoluteUri()
        {
            var request = Request;
            return new System.Text.StringBuilder()
                .Append(request.Scheme)
                .Append("://")
                .Append(request.Host)
                .Append(request.PathBase)
                .Append(request.Path)
                .Append(request.QueryString)
                .ToString();
        }
    }
}
